package Modelo;

import java.util.ArrayList;
import java.util.Random;


public class Godzilla extends Catastrofe {
	
	private Mapa mapaDeAccion;
	
	public Godzilla(Hectarea epicentro,Mapa mapaDeAccion) {
		
		
		this.identificador = CatastrofeIdentificador.GODZILLA;
		this.mapaDeAccion = mapaDeAccion;
		this.epicentroInicial = this.calcularPosicionDeArranque(epicentro);
		
		
	}	
	
	private Hectarea calcularPosicionDeArranque(Hectarea epicentro) {
		int x = epicentro.getCoordenadaX();
		int y = epicentro.getCoordenadaY();
		int distanciaOeste = x-0; // 5
		int distanciaEste = this.mapaDeAccion.getAncho()-1-x; //4
		int distanciaNorte = y-0; // 9
		int distanciaSur = this.mapaDeAccion.getAlto()-1-y; //0
		
		if(distanciaOeste <= distanciaEste){
			if(distanciaNorte <= distanciaSur){
				if(distanciaOeste<=distanciaNorte){
					x = 0;
				}else{
					y = 0;
				}
			}else{
				if(distanciaOeste<=distanciaSur){
					x = 0;
				}else{
					y = this.mapaDeAccion.getAlto()-1;
				}
			}
		}else{
			if(distanciaNorte <= distanciaSur){
				if(distanciaEste<=distanciaNorte){
					x = 0;
				}else{
					y = 0;
				}
			}else{
				if(distanciaEste<=distanciaSur){
					x = 0;
				}else{
					y = this.mapaDeAccion.getAlto()-1;
				}
			}
		}
		return this.mapaDeAccion.obtenerHectareaEnPosicion(x, y);
	}

	public void aplicarDanio(Hectarea hectarea){

		float danioPorcentual = hectarea.obtenerSuperficie().obtenerDanioSiPasaGodzilla();
		hectarea.daniarSuperficie(danioPorcentual);
	}
		

	public ArrayList<Hectarea> obtenerCamino() {
		
		
		TipoDeRecorrido tipoDeRecorrido;
		ArrayList<Hectarea> recorrido;
		PuntosCardinales entrada = this.calcularEntrada();
		
		tipoDeRecorrido = this.radomTipoRecorrido();
		
		recorrido = this.calcularRecorrido(tipoDeRecorrido,entrada);
		
		
		return recorrido;
	}
	
	private TipoDeRecorrido radomTipoRecorrido() {
		
		Random random = new Random();
		double cantOpciones = 2;
		double inicio = 1;
		
		int tipoRandom = (int)(random.nextDouble()*cantOpciones + inicio);
		
		if(tipoRandom == 1){
			return TipoDeRecorrido.RECTO;
		}else{
			return TipoDeRecorrido.ZIGZAG;
		}
	}

	private ArrayList<Hectarea> calcularRecorrido(
			
			TipoDeRecorrido tipoDeRecorrido,PuntosCardinales entrada) {
			ArrayList<Hectarea> recorrido = null;
			if(entrada == PuntosCardinales.OESTE){
				if(tipoDeRecorrido == TipoDeRecorrido.RECTO){
					recorrido = this.calcularRecorridoXRecto();
				}else{
					recorrido = this.calcularRecorridoOesteOSurZigZag();
				}
			}
			
			if(entrada == PuntosCardinales.ESTE){
				if(tipoDeRecorrido == TipoDeRecorrido.RECTO){
					recorrido = this.calcularRecorridoXRecto();
				}else{
					recorrido = this.calcularRecorridoEsteONorteZigZag();
				}
			}
			
			if(entrada == PuntosCardinales.NORTE){
				if(tipoDeRecorrido == TipoDeRecorrido.RECTO){
					recorrido = this.calcularRecorridoYRecto();
				}else{
					recorrido = this.calcularRecorridoEsteONorteZigZag();
				}
			}
			
			if(entrada == PuntosCardinales.SUR){
				if(tipoDeRecorrido == TipoDeRecorrido.RECTO){
					recorrido = this.calcularRecorridoYRecto();
				}else{
					recorrido = this.calcularRecorridoOesteOSurZigZag();
				}
			}
			return recorrido;
	}

	private ArrayList<Hectarea> calcularRecorridoXRecto() {
		
		ArrayList<Hectarea> recorrido = new ArrayList<Hectarea>();
		int coordenadaY = this.epicentroInicial.getCoordenadaY();
		for (int i=0;i<this.mapaDeAccion.getAncho();i++){
			recorrido.add(this.mapaDeAccion.obtenerHectareaEnPosicion(i, coordenadaY));
		}
		return recorrido;
	}
	
	private ArrayList<Hectarea> calcularRecorridoYRecto() {
		
		ArrayList<Hectarea> recorrido = new ArrayList<Hectarea>();
		int coordenadaX = this.epicentroInicial.getCoordenadaX();
		for (int i=0;i<this.mapaDeAccion.getAlto();i++){
			recorrido.add(this.mapaDeAccion.obtenerHectareaEnPosicion(coordenadaX,i));
		}
		return recorrido;
	}
	
	private ArrayList<Hectarea> calcularRecorridoOesteOSurZigZag() {
		
		ArrayList<Hectarea> recorrido = new ArrayList<Hectarea>();
		int i = this.epicentroInicial.getCoordenadaX();
		int j = this.epicentroInicial.getCoordenadaY();
		boolean hectareaFueraDeMapa = false;
		int paso = 0;
		while (!hectareaFueraDeMapa){		
			
			if(this.mapaDeAccion.coordenadaExisteDentroDelMapa(i, j)){
				recorrido.add(this.mapaDeAccion.obtenerHectareaEnPosicion(i, j));
				if(paso % 2 == 0){
					i++;
					paso++;
				}else{
					j--;
					paso++;
				}
			}else{
				hectareaFueraDeMapa = true;
			}
		}
		return recorrido;
	}
	
	private ArrayList<Hectarea> calcularRecorridoEsteONorteZigZag() {
		
		ArrayList<Hectarea> recorrido = new ArrayList<Hectarea>();
		int i = this.epicentroInicial.getCoordenadaX();
		int j = this.epicentroInicial.getCoordenadaY();
		boolean hectareaFueraDeMapa = false;
		int paso = 0;
		while (!hectareaFueraDeMapa){		
			
			if(this.mapaDeAccion.coordenadaExisteDentroDelMapa(i, j)){
				recorrido.add(this.mapaDeAccion.obtenerHectareaEnPosicion(i, j));
				if(paso % 2 == 0){
					i--;
					paso++;
				}else{
					j++;
					paso++;
				}
			}else{
				hectareaFueraDeMapa = true;
			}
		}
		return recorrido;
	}
	
	private PuntosCardinales calcularEntrada() {
		
		if(this.epicentroInicial.getCoordenadaX() == 0){
			return PuntosCardinales.OESTE;
		}else{
			if(this.epicentroInicial.getCoordenadaX() == (this.mapaDeAccion.obtenerAncho()-1)){
				return PuntosCardinales.ESTE;
			}
			else{
				if(this.epicentroInicial.getCoordenadaY() == 0){
					return PuntosCardinales.NORTE;
				}else{
					if(this.epicentroInicial.getCoordenadaY() == (this.mapaDeAccion.obtenerAlto()-1)){
						return PuntosCardinales.SUR;
					}
					else{
						return null;
					}
				}
			}
		}
	}
	
	
	public ArrayList<Hectarea> atacar() {
		ArrayList<Hectarea> hectareasAfectadas = this.obtenerCamino();
		for (int i=0;i<hectareasAfectadas.size();i++){
			this.aplicarDanio(hectareasAfectadas.get(i));
		}
		return hectareasAfectadas;
	}

	public ArrayList<Hectarea> atacar(TipoDeRecorrido tipoRecorrido) {
		ArrayList<Hectarea> hectareasAfectadas = this.obtenerCamino(tipoRecorrido);
		for (int i=0;i<hectareasAfectadas.size();i++){
			this.aplicarDanio(hectareasAfectadas.get(i));
		}
		return hectareasAfectadas;
	}

	private ArrayList<Hectarea> obtenerCamino(TipoDeRecorrido tipoRecorrido) {

			ArrayList<Hectarea> recorrido;
			PuntosCardinales entrada = this.calcularEntrada();
			recorrido = this.calcularRecorrido(tipoRecorrido,entrada);
			
			return recorrido;
	}
	
}

